package com.chenfan.mcn.service.impl;

import com.alibaba.fastjson.JSON;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.dao.DiscountApprovalMapper;
import com.chenfan.mcn.dao.YearFrameContractMapper;
import com.chenfan.mcn.enums.*;
import com.chenfan.mcn.event.EventPublisher;
import com.chenfan.mcn.event.OperateLogEvent;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.mcn.model.DiscountApproval;
import com.chenfan.mcn.model.YearFrameContract;
import com.chenfan.mcn.model.YearSupplementaryAgreement;
import com.chenfan.mcn.dao.YearSupplementaryAgreementMapper;
import com.chenfan.mcn.model.dto.ApprovalFlowDTO;
import com.chenfan.mcn.service.ApprovalCallbackService;
import com.chenfan.mcn.service.ApprovalFlowService;
import com.chenfan.mcn.service.YearSupplementaryAgreementService;
import com.chenfan.mcn.utils.BusinessAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * 年框合同补充协议 服务实现类
 * </p>
 *
 * @author lizhejin
 * @since 2021-01-19
 */
@Service
public class YearSupplementaryAgreementServiceImpl implements YearSupplementaryAgreementService, ApprovalCallbackService {

    @Autowired
    private YearSupplementaryAgreementMapper yearAgreementMapper;

    @Autowired
    private ApprovalFlowService approvalFlowService;

    @Autowired
    private YearFrameContractMapper yearFrameContractMapper;

    @Autowired
    private DiscountApprovalMapper discountApprovalMapper;

    /**
     * 修改年框合同补充协议状态
     *
     * @param yearSupplementaryAgreement {@link YearSupplementaryAgreement}
     * @return {@link Res}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean changeSupplementStatus(YearSupplementaryAgreement yearSupplementaryAgreement) {
        YearSupplementaryAgreement entity = yearAgreementMapper.selectById(yearSupplementaryAgreement.getId());
        BusinessAssert.notNull(entity, McnErrorCode.SUPPLEMENTARY_NOT_EXISTS);
        validateStatus(entity, yearSupplementaryAgreement.getStatus());
        YearSupplementaryAgreement updateEntity = new YearSupplementaryAgreement();
        updateEntity.setId(entity.getId());
        updateEntity.setStatus(yearSupplementaryAgreement.getStatus());
        boolean result = this.updateById(updateEntity);
        if(result) {
            YearSupplementaryAgreement newAgreement = yearAgreementMapper.selectById(yearSupplementaryAgreement.getId());
            if (newAgreement.getStatus() == YearStatusEnum.APPROVAL.code()) {
                approvalFlowService.startProcess(newAgreement.getId(), newAgreement.getYearId(), newAgreement.getAgreementCode(), ApprovalEnum.YEAR_SUPPLEMENTARY_AGREEMENT, JSON.toJSONString(newAgreement), null);
            }
            if (newAgreement.getStatus() == YearStatusEnum.CANCEL.code() || newAgreement.getStatus() == YearStatusEnum.INVALID.code()) {
                approvalFlowService.revokeProcess(newAgreement.getId(), ApprovalEnum.YEAR_SUPPLEMENTARY_AGREEMENT.getProcessId());
                if (newAgreement.getStatus() == YearStatusEnum.INVALID.code()) {
                    //操作日志
                    EventPublisher.post(OperateLogEvent.builder().businessId(entity.getYearId())
                            .businessType(LogBusinessTypeEnum.YEAR_SUPPLEMENTARY_AGREEMENT)
                            .compare(entity, newAgreement)
                            .build());
                }
            }
        }

        return result;
    }

    /**
     * 审批回调
     *
     * @param approvalFlowDTO 流程对对象
     * @param status          最后节点的同意 false 拒绝
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approvalCallback(ApprovalFlowDTO approvalFlowDTO, Boolean status) {
        if (Objects.isNull(status)) {
            //审批流配置-接入待办
            return;
        }
        YearSupplementaryAgreement yearAgreement = yearAgreementMapper.selectById(approvalFlowDTO.getSrcId());
        approvalFlowDTO.addSubmitInfoIfNull(yearAgreement);
        //修改补充协议
        YearSupplementaryAgreement updateAgreement = new YearSupplementaryAgreement();
        updateAgreement.setId(yearAgreement.getId());
        updateAgreement.setStatus(status ? YearStatusEnum.PASSED.code() : YearStatusEnum.REJECTED.code());
        updateAgreement.setUpdateBy(approvalFlowDTO.getUserId());
        updateAgreement.setUpdateName(approvalFlowDTO.getUserName());
        updateAgreement.setUpdateDate(new Date());
        yearAgreementMapper.updateById(updateAgreement);
        //操作日志
        EventPublisher.post(OperateLogEvent.builder().businessId(yearAgreement.getYearId())
                .businessType(LogBusinessTypeEnum.YEAR_SUPPLEMENTARY_AGREEMENT)
                .compare(yearAgreement,  yearAgreementMapper.selectById(yearAgreement.getId()))
                .build(approvalFlowDTO.getUserId(), approvalFlowDTO.getUserName()));
        YearFrameContract yearFrameContract = yearFrameContractMapper.selectById(yearAgreement.getYearId());
        approvalFlowDTO.setSrcCode(yearFrameContract.getYearFrameCode());
        if (Objects.nonNull(yearAgreement.getContactSubjectAfterChange())) {
            boolean includeContractSubject = yearAgreement.getMainChanges().contains(YearAgreementChangeContentEnum.CONTRACT_SUBJECT.getType().toString()) && status;
            if (includeContractSubject) {
                YearFrameContract updateYearFrameContract = new YearFrameContract();
                updateYearFrameContract.setId(yearFrameContract.getId());
                updateYearFrameContract.setUpdateBy(approvalFlowDTO.getUserId());
                updateYearFrameContract.setUpdateName(approvalFlowDTO.getUserName());
                updateYearFrameContract.setUpdateDate(new Date());
                updateYearFrameContract.setContractSubject(yearAgreement.getContactSubjectAfterChange());
                yearFrameContractMapper.updateById(updateYearFrameContract);
                //操作日志
                EventPublisher.post(OperateLogEvent.builder().businessId(yearFrameContract.getId())
                        .businessType(LogBusinessTypeEnum.YEAR_FRAME_CONTRACT)
                        .compare(yearFrameContract, yearFrameContractMapper.selectById(yearAgreement.getYearId()))
                        .build(approvalFlowDTO.getUserId(), approvalFlowDTO.getUserName()));
            }
        }
        if (Objects.nonNull(yearAgreement.getDiscountApprovalAfterChange())) {
            boolean includeDiscountApproval = yearAgreement.getMainChanges().contains(YearAgreementChangeContentEnum.FAVOURED_POLICY.getType().toString()) && status;
            if (includeDiscountApproval) {
                YearFrameContract updateYearFrameContract = new YearFrameContract();
                updateYearFrameContract.setId(yearFrameContract.getId());
                updateYearFrameContract.setUpdateBy(approvalFlowDTO.getUserId());
                updateYearFrameContract.setUpdateName(approvalFlowDTO.getUserName());
                updateYearFrameContract.setUpdateDate(new Date());
                updateYearFrameContract.setDiscountCode(yearAgreement.getDiscountApprovalAfterChange());
                DiscountApproval discountApproval = discountApprovalMapper.selectByDiscountCode(yearAgreement.getDiscountApprovalAfterChange());
                updateYearFrameContract.setDiscountId(discountApproval.getId());
                yearFrameContractMapper.updateById(updateYearFrameContract);
                //操作日志
                EventPublisher.post(OperateLogEvent.builder().businessId(yearFrameContract.getId())
                        .businessType(LogBusinessTypeEnum.YEAR_FRAME_CONTRACT)
                        .compare(yearFrameContract,  yearFrameContractMapper.selectById(yearAgreement.getYearId()))
                        .build(approvalFlowDTO.getUserId(), approvalFlowDTO.getUserName()));
            }
        }
        approvalFlowService.sendNotify(approvalFlowDTO, yearFrameContract.getId(), yearFrameContract.getYearFrameCode()
                , ApprovalEnum.YEAR_SUPPLEMENTARY_AGREEMENT, status, yearAgreement.getCreateBy(), yearAgreement.getCreateName());
    }


    /**
     * 组装修改人信息数据
     *
     * @param yearSupplementaryAgreement {@link YearSupplementaryAgreement}
     * @param yearFrameContract          {@link YearFrameContract}
     */
    public void yearFrameContractDatas(YearSupplementaryAgreement yearSupplementaryAgreement, YearFrameContract yearFrameContract) {
        Long userId = yearSupplementaryAgreement.getUpdateBy() == null ? yearSupplementaryAgreement.getCreateBy() : yearSupplementaryAgreement.getUpdateBy();
        String userName = yearSupplementaryAgreement.getUpdateName() == null ? yearSupplementaryAgreement.getCreateName() : yearSupplementaryAgreement.getUpdateName();
        yearFrameContract.setUpdateBy(userId);
        yearFrameContract.setUpdateName(userName);
        yearFrameContract.setUpdateDate(new Date());
    }

    /**
     * 判断审批状态
     *
     * @param supplementaryAgreement {@link YearSupplementaryAgreement}
     * @param status                 {@link Integer}
     */
    @SuppressWarnings("AlibabaAvoidComplexCondition")
    private void validateStatus(YearSupplementaryAgreement supplementaryAgreement, Integer status) {
        if (supplementaryAgreement.getStatus().equals(YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.YEAR_INVALID);
        }
        if (status.equals(YearStatusEnum.PASSED.code()) || status.equals(YearStatusEnum.REJECTED.code())) {
            if (supplementaryAgreement.getStatus().equals(YearStatusEnum.CANCEL.code())) {
                throw new BusinessException(McnErrorCode.YEAR_CANCELED);
            }
        }
        if (supplementaryAgreement.getStatus().equals(YearStatusEnum.PASSED.code())
                && status.equals(YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.YEAR_NON_VOIDABLE);
        }

        if (supplementaryAgreement.getStatus() == YearStatusEnum.UN_COMMIT.code() &&
                (status != YearStatusEnum.APPROVAL.code() && status != YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.DISCOUNT_APPROVAL_UN_COMMIT_COMMIT_ERROR);
        }
        if (supplementaryAgreement.getStatus() == YearStatusEnum.APPROVAL.code() &&
                (status != YearStatusEnum.CANCEL.code() && status != YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.DISCOUNT_APPROVAL_UN_COMMIT_CANCEL_ERROR);
        }
        if (supplementaryAgreement.getStatus() == YearStatusEnum.PASSED.code() &&
                (status != YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.DISCOUNT_APPROVA_PASSED_ERROR);
        }
        if (supplementaryAgreement.getStatus() == YearStatusEnum.REJECTED.code() &&
                (status != YearStatusEnum.APPROVAL.code() && status != YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.DISCOUNT_APPROVAL_REJECTED_ERROR);
        }
        if (supplementaryAgreement.getStatus() == YearStatusEnum.CANCEL.code() &&
                (status != YearStatusEnum.APPROVAL.code() && status != YearStatusEnum.INVALID.code())) {
            throw new BusinessException(McnErrorCode.DISCOUNT_APPROVAL_CANCEL_ERROR);
        }
    }
}
